package lib

import (
	"encoding/json"
	"fmt"
	"github.com/qiniu/api.v7/auth"
	"github.com/qiniu/api.v7/auth/qbox"
	"github.com/qiniu/api.v7/storage"
	"golang.org/x/net/context"
	"io/ioutil"
	"os"
	"path/filepath"
	"sync"
)

type QiNiu struct {
	AccessKey string `json:"accessKey"`
	SecretKey string `json:"secretKey"`
	Bucket    string `json:"bucket"`
	Url       string `json:"url"`
	Callback  string `json:"callback"`
}

var Qiniu QiNiu

type ProgressRecord struct {
	Progresses []storage.BlkputRet `json:"progresses"`
}

func (this *QiNiu) QinNiuFile(imp_file, filename string) string {
	putPolicy := storage.PutPolicy{
		Scope: Qiniu.Bucket,
	}
	mac := qbox.NewMac(Qiniu.AccessKey, Qiniu.SecretKey)
	upToken := putPolicy.UploadToken(mac)
	cfg := storage.Config{}
	// 空间对应的机房
	cfg.Zone = &storage.ZoneHuadong
	// 是否使用https域名
	cfg.UseHTTPS = false
	// 上传是否使用CDN上传加速
	cfg.UseCdnDomains = false
	// 必须仔细选择一个能标志上传唯一性的 recordKey 用来记录上传进度
	// 我们这里采用 md5(bucket+key+local_path+local_file_last_modified)+".progress" 作为记录上传进度的文件名
	fileInfo, statErr := os.Stat(imp_file)
	if statErr != nil {
		fmt.Println(statErr)
		return ""
	}
	fileSize := fileInfo.Size()
	fileLmd := fileInfo.ModTime().UnixNano()
	recordKey := StrMd5STR(fmt.Sprintf("%s:%s:%s:%s", Qiniu.Bucket, filename, imp_file, fileLmd)) + ".progress"
	// 指定的进度文件保存目录，实际情况下，请确保该目录存在，而且只用于记录进度文件
	recordDir := "/home/shane/server/jw/temp"
	mErr := os.MkdirAll(recordDir, 0755)
	if mErr != nil {
		fmt.Println("mkdir for record dir error,", mErr)
		return " "
	}
	recordPath := filepath.Join(recordDir, recordKey)
	progressRecord := ProgressRecord{}
	// 尝试从旧的进度文件中读取进度
	recordFp, openErr := os.Open(recordPath)
	if openErr == nil {
		progressBytes, readErr := ioutil.ReadAll(recordFp)
		if readErr == nil {
			mErr := json.Unmarshal(progressBytes, &progressRecord)
			if mErr == nil {
				// 检查context 是否过期，避免701错误
				for _, item := range progressRecord.Progresses {
					if storage.IsContextExpired(item) {
						fmt.Println(item.ExpiredAt)
						progressRecord.Progresses = make([]storage.BlkputRet, storage.BlockCount(fileSize))
						break
					}
				}
			}
		}
		recordFp.Close()
	}
	if len(progressRecord.Progresses) == 0 {
		progressRecord.Progresses = make([]storage.BlkputRet, storage.BlockCount(fileSize))
	}
	resumeUploader := storage.NewResumeUploader(&cfg)
	ret := storage.PutRet{}
	progressLock := sync.RWMutex{}
	putExtra := storage.RputExtra{
		Progresses: progressRecord.Progresses,
		Notify: func(blkIdx int, blkSize int, ret *storage.BlkputRet) {
			progressLock.Lock()
			progressLock.Unlock()
			//将进度序列化，然后写入文件
			progressRecord.Progresses[blkIdx] = *ret
			progressBytes, _ := json.Marshal(progressRecord)
			fmt.Println("write progress file", blkIdx, recordPath)
			wErr := ioutil.WriteFile(recordPath, progressBytes, 0644)
			if wErr != nil {
				fmt.Println("write progress file error,", wErr)
			}
		},
	}
	err := resumeUploader.PutFile(context.Background(), &ret, upToken, filename, imp_file, &putExtra)
	if err != nil {
		fmt.Println(err)
		return ""
	}
	//上传成功之后，一定记得删除这个进度文件
	os.Remove(recordPath)
	fmt.Println(ret.Key, ret.Hash)
	return Qiniu.Url + ret.Key
}

func (this *QiNiu) QinNiuDelete(imp_file string) string {
	mac := qbox.NewMac(Qiniu.AccessKey, Qiniu.SecretKey)
	cfg := storage.Config{}
	// 空间对应的机房
	cfg.Zone = &storage.ZoneHuadong
	// 是否使用https域名
	cfg.UseHTTPS = false
	// 上传是否使用CDN上传加速
	cfg.UseCdnDomains = false
	// 构建表单上传的对象
	fmt.Println(Qiniu.AccessKey, Qiniu.SecretKey, Qiniu.Bucket, imp_file)
	bucketManager := storage.NewBucketManager(mac, &cfg)
	key := imp_file
	err := bucketManager.Delete(Qiniu.Bucket, key)
	if err != nil {
		fmt.Println(err)
		return ""
	}
	bu := "空间下文件删除"
	return bu
}
func (this *QiNiu) Tokenss() string {
	putPolicy := storage.PutPolicy{
		Scope: Qiniu.Bucket,
	}
	mac := auth.New(Qiniu.AccessKey, Qiniu.SecretKey)
	upToken := putPolicy.UploadToken(mac)
	//fmt.Println(upToken)

	return upToken
}

func (this *QiNiu)PngUpload( filekey string) string  {
	fmt.Println(filekey,"_______")
	localFile := filekey
	key := filekey
	putPolicy := storage.PutPolicy{
		Scope:               Qiniu.Bucket,
	}
	mac := qbox.NewMac(Qiniu.AccessKey, Qiniu.SecretKey)
	upToken := putPolicy.UploadToken(mac)

	cfg := storage.Config{}
	// 空间对应的机房
	cfg.Zone = &storage.ZoneHuadong
	// 是否使用https域名
	cfg.UseHTTPS = false
	// 上传是否使用CDN上传加速
	cfg.UseCdnDomains = false

	// 构建表单上传的对象
	formUploader := storage.NewFormUploader(&cfg)
	ret := storage.PutRet{}

	// 可选配置
	putExtra := storage.PutExtra{
		Params: map[string]string{
			"x:name": "github logo",
		},
	}
	err := formUploader.PutFile(context.Background(), &ret, upToken, key, localFile, &putExtra)
	if err != nil {
		fmt.Println(err)
		return ""
	}
	//fmt.Println(ret.Key,ret.Hash)
	return Qiniu.Url+ ret.Key
}

func init() {
	jsonFile, err := os.Open("./config/qiniu.json")
	if err != nil {
		fmt.Println("qiniu.json读取错误，请查看" + err.Error())
	}

	data, err := ioutil.ReadAll(jsonFile)
	json.Unmarshal(data, &Qiniu)
	fmt.Println("七牛云", Qiniu)
}
